package eerbaar.v2.app.core;

import java.awt.Canvas;
import java.awt.Container;
import java.awt.Graphics2D;
import java.util.ArrayList;
import java.util.List;

import eerbaar.game.IGame;
import eerbaar.shared.service.ServiceFactory;
import eerbaar.v2.app.GameHelper;
import eerbaar.v2.app.IGameStorage;
import eerbaar.v2.app.extension.IExtension;
import eerbaar.v2.app.forge.Forges;
import eerbaar.v2.app.menu.IMenuProvider;
import eerbaar.v2.app.menu.IMenuService;
import eerbaar.v2.app.menu.MenuService;
import eerbaar.v2.app.mouse.IMouseListener;
import eerbaar.v2.app.mouse.MouseListenerList;
import eerbaar.v2.app.tasks.AppLoop;
import eerbaar.v2.app.tasks.CheckLevelTask;
import eerbaar.v2.app.tasks.DisplayViewTask;
import eerbaar.v2.app.tasks.IGameTask;
import eerbaar.v2.app.tasks.PersonaMoveTask;
import eerbaar.v2.app.tasks.PetMoveTask;
import eerbaar.v2.app.view.HighlightMouse;
import eerbaar.v2.app.view.IView;
import eerbaar.v2.app.view.Standard;
import eerbaar.v2.app.view.View;
import eerbaar.v2.app.view2.PersonaMouse;
import eerbaar.v2.app.view2.PersonaView;

@SuppressWarnings("serial")
public class App extends Canvas implements IApp, IGameStorage {

    private static final App app = new App();

    public static IApp instance() {
        return app;
    }

    private final List<IView> views = new ArrayList<IView>();
    private final List<IExtension> extensions = new ArrayList<IExtension>();
    private final MouseListenerList mouseList = new MouseListenerList();
    private MainWindow mainWindow;
    private final AppLoop loop = new AppLoop();
    private final MenuService menuService = new MenuService();

    private final Forges forges = new Forges();
    private IGame game;

    public App() {
        View view = View.getInstance();
        this.views.add(view);
        this.mouseList.addMouseListener(new HighlightMouse(view));

        PersonaView personaView = new PersonaView(view);
        this.views.add(personaView);
        this.mouseList.addMouseListener(new PersonaMouse(personaView));

        ServiceFactory.register(IMenuService.class, this.menuService);
    }

    @Override
    public void addExtention(IExtension extention) {
        this.extensions.add(extention);
    }

    @Override
    public void addGamePanel(GamePanel panel) {
        this.mainWindow.getRightPanel().addGamePanel(panel);
    }

    @Override
    public void addMenuProvider(IMenuProvider menuProvider) {
        this.menuService.install(menuProvider);
    }

    @Override
    public void addMouseListener(IMouseListener mouseListener) {
        this.mouseList.addMouseListener(mouseListener);
    }

    @Override
    public void addTask(IGameTask task) {
        this.loop.add(task);
    }

    private void doLoop(Graphics2D g) {
        this.loop.doLoop(g);
    }

    @Override
    public Forges getForges() {
        return this.forges;
    }

    @Override
    public IGame getGame() {
        return this.game;
    }

    @Override
    public AppLoop getLoop() {
        return this.loop;
    }

    @Override
    public MainWindow getMainWindow() {
        return this.mainWindow;
    }

    @Override
    public MenuService getMenuService() {
        return this.menuService;
    }

    @Override
    public RightPanel getRightPanel() {
        return this.mainWindow.getRightPanel();
    }

    @Override
    public IView[] getViews() {
        return this.views.toArray(new IView[] {});
    }

    @Override
    public void init(Container container) {

        this.mainWindow = new MainWindow(container);
        for (IExtension e : this.extensions) {
            e.install(app);
        }

        GameHelper.register(this);
        this.forges.getGameForge().start();

        for (IView v : this.views) {
            this.loop.add(new DisplayViewTask(v, this.mainWindow));
        }
        this.loop.add(new PetMoveTask());
        this.loop.add(new CheckLevelTask(this));
        this.loop.add(new PersonaMoveTask());

        this.mainWindow.init(container);

        container.addMouseMotionListener(this.mouseList);
        container.addMouseListener(this.mouseList);
    }

    @Override
    public void paint(Graphics2D g) {

        g.setBackground(Standard.WHITE);
        g.clearRect(0, 0, 500, 500);
        // g.setClip(0, 0, 500, 500);
        g.setColor(Standard.MEDIUM_SEA_GREEN);
        g.fillRoundRect(0, 0, 500, 500, 20, 20);
        g.setColor(Standard.BLACK);
        g.drawRoundRect(0, 0, 500, 500, 20, 20);

        doLoop(g);

        g.dispose();

    }

    @Override
    public void setGame(IGame game) {
        this.game = game;
    }
}
